<!DOCTYPE html>
<html>
<head>
    <title>Electromagnetic Field Diagram</title>
    <style>
        canvas {
            border: 1px solid #eee;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="400" height="550"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Style settings
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 1.5;
        ctx.font = 'italic 20px Times New Roman';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        // --- Helper function to draw an arrow ---
        function drawArrow(fromX, fromY, toX, toY, headLength) {
            const dx = toX - fromX;
            const dy = toY - fromY;
            const angle = Math.atan2(dy, dx);
            ctx.beginPath();
            ctx.moveTo(fromX, fromY);
            ctx.lineTo(toX, toY);
            ctx.lineTo(toX - headLength * Math.cos(angle - Math.PI / 6), toY - headLength * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headLength * Math.cos(angle + Math.PI / 6), toY - headLength * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        // --- Core parameters ---
        const O = { x: 200, y: 420 };
        const rodLength = 280;
        const theta = 22 * Math.PI / 180; // Angle in radians
        const rodThickness = 6;

        // --- Calculated coordinates ---
        const P = {
            x: O.x + rodLength * Math.sin(theta),
            y: O.y - rodLength * Math.cos(theta)
        };
        const O_prime = {
            x: O.x,
            y: P.y
        };
        
        // --- Drawing sequence ---

        // 1. Draw Axis OO' (dash-dot line)
        ctx.beginPath();
        ctx.setLineDash([8, 4, 2, 4]); 
        ctx.moveTo(O.x, O.y + 20);
        ctx.lineTo(O_prime.x, O_prime.y - 85);
        ctx.stroke();
        ctx.setLineDash([]); // Reset line dash

        // 2. Draw Magnetic Field Vector B
        ctx.lineWidth = 1.5;
        drawArrow(O_prime.x, O_prime.y - 15, O_prime.x, O_prime.y - 75, 10);
        ctx.fillText('B', O_prime.x + 18, O_prime.y - 75);

        // 3. Draw dashed ellipse (path of P)
        const radiusX = P.x - O_prime.x;
        const radiusY = radiusX / 3.5;
        ctx.beginPath();
        ctx.setLineDash([6, 4]);
        ctx.ellipse(O_prime.x, O_prime.y, radiusX, radiusY, 0, 0, 2 * Math.PI);
        ctx.stroke();
        ctx.setLineDash([]);

        // 4. Draw the Rod OP
        const dx = P.x - O.x;
        const dy = P.y - O.y;
        const length = Math.sqrt(dx * dx + dy * dy);
        const udx = dx / length;
        const udy = dy / length;
        const px = -udy; // Perpendicular vector component x
        const py = udx;  // Perpendicular vector component y
        
        const halfThick = rodThickness / 2;

        ctx.beginPath();
        ctx.moveTo(O.x - halfThick * px, O.y - halfThick * py);
        ctx.lineTo(P.x - halfThick * px, P.y - halfThick * py);
        ctx.lineTo(P.x + halfThick * px, P.y + halfThick * py);
        ctx.lineTo(O.x + halfThick * px, O.y + halfThick * py);
        ctx.closePath();
        
        // Fill the rod with a light gray color similar to the original image
        ctx.fillStyle = '#f0f0f0';
        ctx.fill();
        // Stroke the outline of the rod
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 1.5;
        ctx.stroke();
        
        // 5. Add Labels: O, O', P, ω, θ
        ctx.fillStyle = 'black';
        ctx.font = 'italic 20px Times New Roman';
        ctx.fillText('O', O.x - 18, O.y);
        ctx.fillText("O'", O_prime.x - 20, O_prime.y);
        ctx.fillText('P', P.x + 10, P.y - 5);
        ctx.font = 'italic 24px Times New Roman';
        ctx.fillText('ω', O_prime.x + radiusX * 0.6, O_prime.y - radiusY - 15);
        
        // 6. Draw and label angle θ
        ctx.font = 'italic 20px Times New Roman';
        ctx.beginPath();
        const angleRadius = 40;
        // Angles for arc are relative to the positive x-axis. Vertical up is -PI/2.
        ctx.arc(O.x, O.y, angleRadius, -Math.PI / 2, -Math.PI / 2 + theta, false);
        ctx.stroke();
        
        // Position the θ label inside the arc
        const thetaLabelAngle = -Math.PI / 2 + theta / 2;
        const thetaLabelRadius = angleRadius * 0.6;
        ctx.fillText('θ', O.x + thetaLabelRadius * Math.cos(thetaLabelAngle), O.y + thetaLabelRadius * Math.sin(thetaLabelAngle) + 5);

        // 7. Add caption at the bottom
        ctx.font = '18px "SimSun", "STSong"';
        ctx.fillStyle = 'black';
        ctx.fillText('习题 9-7 图', canvas.width / 2, canvas.height - 25);

    </script>
</body>
</html>